package com.ziven.common.widget.setting;

import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.ziven.common.widget.R;
import com.ziven.common.widget.WidgetUtils;
import com.ziven.easygo.EasyGos;
import com.ziven.easygo.autowired.EasyGo;
import com.ziven.easygo.design.mvp.AbstractOneData;
import com.ziven.easygo.design.mvp.OneData;
import com.ziven.easygo.design.mvp.OneModel;
import com.ziven.easygo.ui.AbstractOneDataFragment;
import com.ziven.easygo.util.EasyUtils;
import com.ziven.easygo.util.ResourceUtils;
import com.ziven.easygo.util.Standard;

import java.util.List;
import java.util.Map;

/**
 * @author Ziven
 */
public final class PreferenceFragment extends AbstractOneDataFragment implements Standard, SharedPreferences.OnSharedPreferenceChangeListener {

    public static final String PATH = "com.ziven.common.widget.setting.PreferenceItemsFactory";
    public static final int TYP_BACKGROUND = 100;
    private PreferenceItemsFactory itemsFactory;
    private PreferenceAdapter adapter;
    private boolean isRegisterSharedPreferenceChange = false;
    private String preferenceItemsFactoryId = PATH;

    public static PreferenceFragment newInstance(@NonNull PreferenceItemsFactory factory) {
        return new PreferenceFragment().accept(my -> my.itemsFactory = factory);
    }

    public static PreferenceFragment newInstance() {
        return new PreferenceFragment();
    }

    public PreferenceFragment setPreferenceItemsFactory(@NonNull PreferenceItemsFactory factory) {
        itemsFactory = factory;
        return this;
    }

    public PreferenceFragment setPreferenceItemsFactoryId(String id) {
        if(!TextUtils.isEmpty(id)) {
            preferenceItemsFactoryId = id;
        }
        return this;
    }

    private PreferenceItemsFactory getItemsFactory() {
        if(itemsFactory != null) {
            return itemsFactory;
        }
        //From Activity
        if(getActivity() instanceof PreferenceItemsFactory) {
            itemsFactory = (PreferenceItemsFactory) getActivity();
        }
        //From Application
        if(itemsFactory == null && ResourceUtils.getContext() instanceof PreferenceItemsFactory) {
            itemsFactory = (PreferenceItemsFactory) ResourceUtils.getContext();
        }
        //Form Method
        if(itemsFactory == null) {
            initPreferenceItemsFactory();
        }
        //Throw Exception
        if(itemsFactory == null) {
            throw new NullPointerException("Items factory is null.");
        }
        itemsFactory.setCallGetPreferenceItems(() -> getOnePresenter().obtainOneData());
        return itemsFactory;
    }

    private void initPreferenceItemsFactory() {
        EasyGos.getEasyGo().easyGo(
                EasyGo.Transition.of(PATH)
                        .param(preferenceItemsFactoryId)
                        .carry(data -> {
                            if(data instanceof PreferenceItemsFactory) {
                                itemsFactory = (PreferenceItemsFactory) data;
                            }
                        }));
    }

    private PreferenceAdapter getAdapter() {
        if(adapter == null) {
            adapter = new PreferenceAdapter(getItemsFactory());
        }
        return adapter;
    }

    @NonNull
    @Override
    protected Class<? extends OneModel> obtainOneModelClass() {
        return PreferenceFragmentModel.class;
    }

    @Override
    protected Object obtainLayout() {
        return R.layout.fragment_recyclerview_container;
    }

    @Override
    protected void createdView(@NonNull View root) {
        getItemsFactory().getPreferenceItemEffect(TYP_BACKGROUND).takeEffect(root);
        RecyclerView rv = getView2(R.id.recycler_view);
        rv.setLayoutManager(new LinearLayoutManager(root.getContext()));
        rv.setAdapter(getAdapter());
        getOnePresenter().obtainOneData();
    }

    @Override
    protected void destroyView() {

    }

    @Override
    public void layoutOneData(@NonNull AbstractOneData data) {
        List<BasePreferenceItem> list = getItemsFactory().getPreferenceItems();
        getAdapter().getDataProvider().setList(list).forEach(BasePreferenceItem::afterDataLoaded);
        if(!isRegisterSharedPreferenceChange && shouldRegisterSharedPreferenceChange(list)) {
            isRegisterSharedPreferenceChange = true;
            WidgetUtils.getSp().registerOnSharedPreferenceChangeListener(this);
        }
        EasyUtils.notifyDataSetChanged(getAdapter());
    }

    private boolean shouldRegisterSharedPreferenceChange(@NonNull List<BasePreferenceItem> list) {
        for(BasePreferenceItem item : list) {
            if(item.relatedIds != null && item.relatedIds.size() > 0) {
                return true;
            }
        }
        return false;
    }

    @Override
    protected void destroyActivity() {
        if(isRegisterSharedPreferenceChange) {
            isRegisterSharedPreferenceChange = false;
            WidgetUtils.getSp().unregisterOnSharedPreferenceChangeListener(this);
        }
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if(!TextUtils.isEmpty(key)) {
            notifyItem(key);
        }
    }

    private void notifyItem(@NonNull String key) {
        List<BasePreferenceItem> list = getAdapter().getDataProvider().getList();
        if(list != null && !list.isEmpty()) {
            for(int i=0; i<list.size(); i++) {
                if(list.get(i).hasRelatedId(key)) {
                    getAdapter().notifyItemChanged(i);
                }
            }
        }
    }

    public static class PreferenceFragmentModel extends OneModel {

        @Override
        protected void obtainOneData(@Nullable Context c, @Nullable Map<Object, Object> params) {
            obtainedOneData(OneData.of());
        }
    }
}
